package com.atguigu.yygh.service.impl;

import com.alibaba.excel.EasyExcel;
import com.atguigu.yygh.exception.YyghException;
import com.atguigu.yygh.listener.DictListener;
import com.atguigu.yygh.mapper.DictMapper;
import com.atguigu.yygh.model.cmn.Dict;
import com.atguigu.yygh.result.ResultCodeEnum;
import com.atguigu.yygh.service.DictService;
import com.atguigu.yygh.vo.cmn.DictEeVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zr
 * @date 2021/12/10 12:52
 */
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {

    @Override
    @Cacheable(value = "dict", keyGenerator = "keyGenerator")
    public List<Dict> findChildDataByParentId(long parentId) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        List<Dict> dictList = baseMapper.selectList(queryWrapper);
        // 遍历List 获取Id
        for (Dict dict : dictList) {
            Long id = dict.getId();
            // 判断id下是否有子节点
            boolean isChildren = this.isChildren(id);
            dict.setHasChildren(isChildren);
        }
        return dictList;
    }

    @Override
    public void exportData(HttpServletResponse response) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = "dict";
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        // 查出数据库中的数据
        List<Dict> dictList = baseMapper.selectList(null);
        List<DictEeVo> eeVoList = new ArrayList<>();
        // 首先将数据进行遍历 然后将Dict->DictEeVo
        for (Dict dict : dictList) {
            DictEeVo dictEeVo = new DictEeVo();
            BeanUtils.copyProperties(dict, dictEeVo);
            // 将dictEeVo添加到eeVoList里面
            eeVoList.add(dictEeVo);
        }
        // 使用EasyExcel写数据
        try {
            EasyExcel.write(response.getOutputStream(), DictEeVo.class)
                    .sheet(fileName)
                    .doWrite(eeVoList);
        } catch (IOException e) {
            throw new YyghException("导出失败", 201);
        }
    }

    /**
     * 导入
     * allEntries = true: 方法调用后清空所有缓存
     *
     * @param file
     */
    @CacheEvict(value = "dict", allEntries = true)
    @Override
    public void importData(MultipartFile file) {

        try {
            EasyExcel.read(file.getInputStream(), DictEeVo.class, new DictListener(baseMapper))
                    .sheet()
                    .doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getDictName(String dictCode, String value) {
        // 首先进行判断  如果dictCode为空 则按照value进行查询
        if (StringUtils.isEmpty(dictCode)) {
            QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("value", value);
            Dict dict = baseMapper.selectOne(queryWrapper);
            return dict.getName();
        }
        // 根据dictCode 和value进行查询
        // 首先根据dictCode获取dict对象
        Dict codeDict = this.getDictByDictCode(dictCode);
        Long dictId = codeDict.getId();
        // 根据parent_id 和value进行查询
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", dictId);
        queryWrapper.eq("value", value);
        Dict finalDict = baseMapper.selectOne(queryWrapper);
        return finalDict.getName();
    }

    @Override
    public List<Dict> findByDictCode(String dictCode) {
        Dict dict = this.getDictByDictCode(dictCode);
        // 进行判空
        if (dict == null) {
            throw new YyghException(ResultCodeEnum.DATA_ERROR);
        }
        // 根据id获取子节点
        List<Dict> dictList = this.findChildDataByParentId(dict.getId());
        return dictList;
    }

    /**
     * 根据dictCode获取dict对象
     *
     * @param dictCode
     * @return
     */
    private Dict getDictByDictCode(String dictCode) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper();
        queryWrapper.eq("dict_code", dictCode);
        return baseMapper.selectOne(queryWrapper);
    }

    /**
     * 判断节点下是否有子节点
     *
     * @param id
     * @return
     */
    private boolean isChildren(Long id) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        Integer count = baseMapper.selectCount(queryWrapper);
        return count > 0;
    }
}
